---
title: Sponsored Transactions
description: A sponsored transaction is when one Sui address pays the gas fee for a transaction submitted by another address. Sponsored transactions can help facilitate user onboarding and simplified asset management.
keywords: [ sponsored transaction, how to sponsor a transaction, sponsor a transaction, pay gas for another address, can you pay gas for another address, sponsoring a transaction, paying fee for another user, paying gas for another user, paying for someone else, paying gas for someone else, sponsoring someone's transaction ]
---

A _sponsored transaction_ is when one address pays the gas fee for a [transaction](/concepts/transactions.mdx) submitted by another address. You can use sponsored transactions to cover the fees for transactions initiated by users on your site or dApp. This removes a significant obstacle that Web2 users encounter when entering Web3, as they often have to purchase tokens to cover the gas fee and execute a transaction on-chain. 

You can provide a wildcard `GasData` object to users. The object covers the gas fees for a user transaction. The `GasData` object covers any fee amount determined for the transaction as long as the budget is sufficient.

Sponsored transactions can also facilitate asset management as you don't need to maintain multiple accounts with SUI tokens to transfer funds.

## Potential risks

The most significant risk when using sponsored transactions is [equivocation](/concepts/sui-architecture/epochs.mdx).  An equivocation occurs when an owned object's pair (`ObjectID`, `SequenceNumber`) is concurrently used in multiple non-finalized transactions. To avoid double spending, validators lock objects as they validate transactions.

In some scenarios, sponsored transactions can result in locking all associated owned objects. 

To equivocate, either the user or the sponsor signs and submits another transaction that attempts to manipulate an owned object in the original transaction. Because only the object owner can use an owned object, only the user and sponsor can cause this condition.

## Create a user-initiated sponsored transaction

A user-initiated sponsored transaction involves the following steps:

1. A user initializes a `GasLessTransactionData` transaction.

1. The user sends `GasLessTransactionData` to the sponsor.

1. The sponsor validates the transaction, constructs `TransactionData` with gas fees, and then signs `TransactionData`.

1. The sponsor sends the signed `TransactionData` and the sponsor `Signature` back to the user.

1. The user verifies and then signs `TransactionData` and sends the dual-signed transaction to Sui network through a full node or the sponsor.

### `GasLessTransactionData`

`GasLessTransactionData` is `TransactionData` without `GasData`. It is not a `sui-core` data structure; it is only an interface between user and sponsor.

The following example constructs a `GasLessTransactionData`  object:

```rust
pub struct GasLessTransactionData {
    pub kind: TransactionKind,
    sender: SuiAddress,
    …
}
```

## Create a sponsor-initiated sponsored transaction  

A sponsor-initiated sponsored transaction involves the following steps:

1. A sponsor constructs a `TransactionData` object that contains the transaction details and associated gas fee data. The sponsor signs it to generate a `Signature` before sending it to a user. You can send unsigned `TransactionData` via email, SMS, or an application interface.

1. The user checks the transaction and signs it to generate the second `Signature` for the transaction.

1. The user submits the dual-signed transaction to a Sui full node or sponsor to execute it.

You can use a sponsor-initiated sponsored transaction as an advertiser, or to incentivize specific user actions without requiring the user to pay for gas fees.

## Create sponsored transactions using a `GasData` object

To use a `GasData` object to sponsor the gas fees for a transaction, create a `GasData` object that covers the fees determined for the transaction. The user doesn't need to know how much the fee is or approve it.

A sponsor transaction using a `GasData` object involves the following steps:

1. The sponsor provides a `GasData` object to a user.

1. The user constructs `TransactionData` and signs it to generate a `Signature`.

1. The user sends the `TransactionData` and the `Signature` to the sponsor.

1. The sponsor confirms the `TransactionData` and then signs it.

1. The sponsor submits the dual-signed `TransactionData` to a full node to execute the transaction.

## Sponsored transaction data structure

The following code block describes the `TransactionData` structure for sponsored transactions and `GasObject`. You can view the [source code](https://github.com/MystenLabs/sui/blob/224a28ed9dece21a952547896bd5d794bdf8b562/crates/sui-types/src/transaction.rs) in the Sui GitHub repository.

**`TransactionData` structure**
```rust
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
pub struct TransactionDataV1 {
    pub kind: TransactionKind,
    pub sender: SuiAddress,
    pub gas_data: GasData,
    pub expiration: TransactionExpiration,
}
```

**`GasData` structure**
```rust
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
pub struct GasData {
    pub payment: Vec<ObjectRef>,
    pub owner: SuiAddress,
    pub price: u64,
    pub budget: u64,
}
```

## Create a Sui gas station

On Sui, the term _gas station_ refers to a concept where you set up processes to sponsor user transactions. You can customize a gas station to support the specific user-facing functionality you need. Some example use cases for a Sui gas station include:

- Monitor real-time gas prices on the network to determine the gas price that the station provides.

- Track usage of gas provided to users on the network.

- Gas pool management, such as using specific gas objects to minimize costs or reduce the risk of a large amount of locked objects that remain illiquid while locked.

Depending on the nature of your gas station, you can apply different authorization rules to avoid being spammed by bad actors. Possible policies include rate limiting gas requests per account or per IP address, or only accepting requests with a valid authorization header.

:::warning 

For all gas objects that you provide as a sponsor, you should track if users ever try to equivocate and lock objects. If you detect such behavior, block the user or requester accordingly.

:::

### Example

The following Rust SDK code examples demonstrate how to implement a Sui gas station that supports each of the sponsored transaction types described previously.

#### User-initiated sponsored transactions

Use the API endpoint to receive `GaslessTransaction` transactions and return a sole-signed `SenderSignedData` object.

```rust
pub fn request_gas_and_signature(gasless_tx: GaslessTransaction) -> Result<SenderSignedData, Error>;
```

#### Sponsored transactions with `GasData` objects

Use the API endpoint to receive single-signed `SenderSignedData` and return the result of the transaction.

```rust
pub fn submit_sole_signed_transaction(sole_signed_data: SenderSignedData) -> Result<(Transaction, CertifiedTransactionEffects), Error>;
```

Alternatively, use the API endpoint to return a `GasData` object.

```rust
pub fn request_gas(/*requirement data*/) -> Result<GasData, Error>;
```

### User and sponsor-initiated transaction

Use the API endpoint to receive dual-signed `SenderSignedData` and return the result of the transaction.

```rust
pub fn submit_dual_signed_transaction(dual_signed_data: SenderSignedData) -> Result<(Transaction, CertifiedTransactionEffects), Error>;
```

For user and sponsor-initiated transactions, users can submit the dual-signed transaction via either a sponsor or a full node.
